package zhoug.zui.dialog.date;

import android.content.Context;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.NumberPicker;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import androidx.annotation.NonNull;
import zhoug.common.anim.ZAnimations;
import zhoug.common.utils.StringUtils;
import zhoug.common.utils.TimeUtils;
import zhoug.logging.Logger;
import zhoug.zui.R;
import zhoug.zui.ZUINumberPicker;
import zhoug.zui.date.DateSelectInterface;
import zhoug.zui.dialog.ZUIButtonDialog;

/**
 * 日期选择器
 * 支持设置最大年月日
 *
 * @Author 35574
 * @Date 2020/8/3
 * @Description
 */
public class ZUIDateChooser extends ZUIButtonDialog implements NumberPicker.OnValueChangeListener, View.OnClickListener {
    private static final String TAG = ">>>ZUIDateChooser";
    private static final boolean DEBUG = false;
    public static final int TYPE_DATE = 1;//0001 年月日
    public static final int TYPE_TIME = 2;//0010 时分
    public static final int TYPE_DATE_TIME = 3;//0011 年月日时分

    private ZUINumberPicker mNumberPickerYear;//年
    private ZUINumberPicker mNumberPickerMonth;//月
    private ZUINumberPicker mNumberPickerDay;//日
    private ZUINumberPicker mNumberPickerHour;//时
    private ZUINumberPicker mNumberPickerMinute;//分
    /**
     * 日期后面的单位
     */
    private TextView mDateTvYear;//
    private TextView mDateTvMonth;
    private TextView mDateTvDay;
    private TextView mDateTvHour;
    private TextView mDateTvMinute;

    private int mType = TYPE_DATE;
    private Callback mCallback;

    private String mYear;//年
    private String mMonth;//月
    private String mDay;//日
    private String mHour;//时
    private String mMinute;//分
    private String mMaxYear;//最大年
    private String mMaxMonth;//最大月
    private String mMaxDay;//最大日

    private ArrayList<String> dayList;//天数
    private static final String YEAR = "2200";
    private boolean mShowYear = true;
    private boolean mShowMonth = true;
    private boolean mShowDay = true;
    private boolean mShowHour = true;
    private boolean mShowMinute = true;

    public static final String PATTERN_DATE = "yyyy-MM-dd";
    public static final String PATTERN_DATE_TIME = "yyyy-MM-dd HH:mm:ss";
    public static final int HORIZONTAL = DateSelectInterface.HORIZONTAL;//水平对齐
    public static final int VERTICAL = DateSelectInterface.VERTICAL;//垂直对齐
    /**
     * 对齐方式
     */
    private int mOrientation = HORIZONTAL;

    public ZUIDateChooser(@NonNull Context context) {
        this(context, 0);
    }

    public ZUIDateChooser(@NonNull Context context, int themeResId) {
        this(context, themeResId, 0, 0);
    }

    protected ZUIDateChooser(@NonNull Context context, int themeResId, int defStyleAttr, int defStyleRes) {
        super(context, themeResId, defStyleAttr, defStyleRes);

    }

    @Override
    protected void initialize(@NonNull Context context, int defStyleAttr, int defStyleRes) {
        super.initialize(context, defStyleAttr, defStyleRes);
        setWindowAnimations(ZAnimations.ANIM_DOWN);
        setAttributes(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT, Gravity.BOTTOM);
        setFullWidth(true);
    }

    @Override
    protected int getLayoutResId() {
        return R.layout.zui_data_chooser;
    }

    @Override
    protected void init(Bundle savedInstanceState) {

        //初始化View
        mNumberPickerYear = findViewById(R.id.date_numberPicker_year);
        mNumberPickerMonth = findViewById(R.id.date_numberPicker_month);
        mNumberPickerDay = findViewById(R.id.date_numberPicker_day);
        mNumberPickerHour = findViewById(R.id.date_numberPicker_hour);
        mNumberPickerMinute = findViewById(R.id.date_numberPicker_minute);
        mDateTvYear = findViewById(R.id.date_tv_year);
        mDateTvMonth = findViewById(R.id.date_tv_month);
        mDateTvDay = findViewById(R.id.date_tv_day);
        mDateTvHour = findViewById(R.id.date_tv_hour);
        mDateTvMinute = findViewById(R.id.date_tv_minute);
        ViewGroup containerDate = findViewById(R.id.container_date);
        ViewGroup containerTime = findViewById(R.id.container_time);
        showYear(mShowYear);
        showMonth(mShowMonth);
        showDay(mShowDay);
        showHour(mShowHour);
        showMinute(mShowMinute);
        //选择日期
        if (mType == TYPE_DATE) {
            containerDate.setVisibility(View.VISIBLE);
            containerTime.setVisibility(View.GONE);
        } else if (mType == TYPE_TIME) {
            //选择时间
            containerDate.setVisibility(View.GONE);
            containerTime.setVisibility(View.VISIBLE);
        } else {
            //选择日期和时间
            containerDate.setVisibility(View.VISIBLE);
            containerTime.setVisibility(View.VISIBLE);
        }
        mNumberPickerYear.setOnValueChangedListener(this);
        mNumberPickerMonth.setOnValueChangedListener(this);
        setNegativeListener("取消", this);
        setPositiveListener("确定", this);
        init();
        initDate();
        super.init(savedInstanceState);
    }


    /**
     * 初始化日期
     */
    private void init() {
        try {
            //默认显示现在的日期
            String[] split = TimeUtils.getCurrentTime("yyyy-MM-dd-HH-mm").split("-");
            if (mYear == null) {
                if (mMaxYear != null && TimeUtils.compareInt(split[0], mMaxYear) > 0) {
                    mYear = mMaxYear;
                } else {
                    mYear = split[0];
                }
            }
            if (mMonth == null) {
                if (mMaxMonth != null && TimeUtils.compareInt(split[1], mMaxMonth) > 0) {
                    mMonth = mMaxMonth;
                } else {
                    mMonth = split[1];
                }
            }
            if (mDay == null) {
                if (mMaxDay != null && TimeUtils.compareInt(split[2], mMaxDay) > 0) {
                    mDay = mMaxDay;
                } else {
                    mDay = split[2];
                }
            }
            if (mHour == null) {
                mHour = split[3];
            }
            if (mMinute == null) {
                mMinute = split[4];
            }
            if (DEBUG) {
                Logger.d(TAG, "init date:" + mYear + "-" + mMonth + "-" + mDay + " " + mHour + ":" + mMinute);
                Logger.d(TAG, "init maxDate:" + mMaxYear + "-" + mMaxMonth + "-" + mMaxDay);
            }
        } catch (Exception e) {
//            e.printStackTrace();
        }
    }

    private void initDate() {
        //初始化年
        ArrayList<String> yearList = null;
        if (mMaxYear == null) {
            yearList = TimeUtils.getYearList(YEAR);
        } else {
            yearList = TimeUtils.getYearList(mMaxYear);
        }
        String[] years = new String[yearList.size()];
        yearList.toArray(years);
        mNumberPickerYear.setMinValue(0);
        mNumberPickerYear.setMaxValue(years.length - 1);
        mNumberPickerYear.setDisplayedValues(years);
        setSelectedYear(mYear);

        //初始化月
        initMonth(mYear);
        mNumberPickerMonth.setMinValue(0);
        setSelectedMonth(mMonth);
        //初始化日
        initDay(mYear, mMonth);
        mNumberPickerDay.setMinValue(0);
        setSelectedDay(mDay);

        //初始化时
        ArrayList<String> hourList = TimeUtils.getHourList();
        String[] hours = new String[hourList.size()];
        hourList.toArray(hours);
        mNumberPickerHour.setMinValue(0);
        mNumberPickerHour.setMaxValue(hours.length - 1);
        mNumberPickerHour.setDisplayedValues(hours);
        setSelectedHour(mHour);
        //初始化分
        ArrayList<String> minuteList = TimeUtils.getMinuteList();
        String[] minutes = new String[minuteList.size()];
        minuteList.toArray(minutes);
        mNumberPickerMinute.setMinValue(0);
        mNumberPickerMinute.setMaxValue(minutes.length - 1);
        mNumberPickerMinute.setDisplayedValues(minutes);
        setSelectedMinute(mMinute);

    }

    /**
     * 初始化月
     *
     * @param year
     */
    private void initMonth(String year) {
        ArrayList<String> monthList = null;
        String[] displayedValues = mNumberPickerMonth.getDisplayedValues();
        if (displayedValues == null) {
            if (mMaxMonth != null && !"12".equals(mMaxMonth) && year.equals(mMaxYear)) {
                monthList = TimeUtils.getMonthList(mMaxMonth);
                if (DEBUG) {
                    Logger.d(TAG, "initMonth1:" + monthList.size());
                }
            } else {
                monthList = TimeUtils.getMonthList("12");
                if (DEBUG) {
                    Logger.d(TAG, "initMonth2:" + monthList.size());
                }
            }
        } else {
            //设置了最大月
            if (mMaxMonth != null && !"12".equals(mMaxMonth)) {
                //切换到了最大月
                if (displayedValues.length == 12 && year.equals(mMaxYear)) {
                    monthList = TimeUtils.getMonthList(mMaxMonth);
                    if (DEBUG) {
                        Logger.d(TAG, "initMonth:切换到了最大月:" + monthList.size());
                    }
                } else if (displayedValues.length != 12 && !year.equals(mMaxYear)) {
                    //最大月切出
                    monthList = TimeUtils.getMonthList("12");
                    if (DEBUG) {
                        Logger.d(TAG, "initMonth:最大月切出:" + monthList.size());

                    }

                }
            }
        }
        if (monthList != null) {
            String[] months = new String[monthList.size()];
            monthList.toArray(months);
            mNumberPickerMonth.setDisplayedValues(null);
            mNumberPickerMonth.setMaxValue(months.length - 1);
            mNumberPickerMonth.setDisplayedValues(months);
        }


    }

    /**
     * 初始化日
     *
     * @param year
     * @param month
     */
    private void initDay(String year, String month) {
        if (dayList == null) {
            dayList = new ArrayList<>();
        }
        dayList.clear();
        TimeUtils.getDays(year, month, dayList);
        //最大日期
        if (year.equals(mMaxYear) && month.equals(mMaxMonth)) {
            if (mMaxDay != null) {
                try {
                    int endDay = Integer.parseInt(mMaxDay);
                    //移除最大值以后的日期
                    if (dayList.size() > endDay) {
                        for (int i = dayList.size() - 1; i > endDay - 1; i--) {
                            dayList.remove(i);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        String[] days = new String[dayList.size()];
        dayList.toArray(days);
//        Log.i(TAG, "initDay: ");
        mNumberPickerDay.setDisplayedValues(null);//解决ArrayIndexOutOfBoundsException
        mNumberPickerDay.setMaxValue(days.length - 1);
        mNumberPickerDay.setDisplayedValues(days);

    }

    /**
     * 设置选择的年
     *
     * @param year
     */
    private void setSelectedYear(String year) {
        String[] years = mNumberPickerYear.getDisplayedValues();
        for (int i = 0; i < years.length; i++) {
            if (years[i].equals(year)) {
                mNumberPickerYear.setValue(i);
                break;
            }
        }
    }

    /**
     * 设置选择的月
     *
     * @param month
     */
    private void setSelectedMonth(String month) {
        String[] months = mNumberPickerMonth.getDisplayedValues();
        for (int i = 0; i < months.length; i++) {
            if (months[i].equals(month)) {
                mNumberPickerMonth.setValue(i);
                break;
            }
        }
    }

    /**
     * 设置选择的日
     *
     * @param day
     */
    private void setSelectedDay(String day) {
        String[] days = mNumberPickerDay.getDisplayedValues();
        for (int i = 0; i < days.length; i++) {
            if (days[i].equals(day)) {
                mNumberPickerDay.setValue(i);
                break;
            }
        }
    }

    /**
     * 设置选择的时
     *
     * @param hour
     */
    private void setSelectedHour(String hour) {
        String[] hours = mNumberPickerHour.getDisplayedValues();
        for (int i = 0; i < hours.length; i++) {
            if (hours[i].equals(hour)) {
                mNumberPickerHour.setValue(i);
                break;
            }
        }
    }

    /**
     * 设置选择的分
     *
     * @param minute
     */
    private void setSelectedMinute(String minute) {
        String[] minutes = mNumberPickerMinute.getDisplayedValues();
        for (int i = 0; i < minutes.length; i++) {
            if (minutes[i].equals(minute)) {
                mNumberPickerMinute.setValue(i);
                break;
            }
        }
    }

    @Override
    public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
        int id = picker.getId();
        if (id == R.id.date_numberPicker_year) {
            //年
            String[] years = picker.getDisplayedValues();
            String oldyear = years[oldVal];
            String newyear = years[newVal];
            //当前选择的月为2月
            if (mNumberPickerMonth.getValue() == 1) {
                if (TimeUtils.isLeapYear(oldyear) != TimeUtils.isLeapYear(newyear)) {
                    initDay(newyear, "2");
                }
            }
            initMonth(newyear);
            String newMonth = mNumberPickerMonth.getDisplayedValues()[mNumberPickerMonth.getValue()];
            if (DEBUG) {
                Logger.d(TAG, "onValueChange:newyear=" + newyear + ",newMonth=" + newMonth);

            }
            initDay(newyear, newMonth);

        } else if (id == R.id.date_numberPicker_month) {
            //月
            int v = newVal + 1;
            String newMonth = v > 10 ? "" + v : "0" + v;

            String year = mNumberPickerYear.getDisplayedValues()[mNumberPickerYear.getValue()];
            if (DEBUG) {
                Logger.d(TAG, "onValueChange:year=" + year + ",newMonth=" + newMonth);

            }

            initDay(year, newMonth);
        }
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.btn_negative) {
            dismiss();
        } else if (v.getId() == R.id.btn_positive) {
            mYear = mNumberPickerYear.getDisplayedValues()[mNumberPickerYear.getValue()];
            mMonth = mNumberPickerMonth.getDisplayedValues()[mNumberPickerMonth.getValue()];
            mDay = mNumberPickerDay.getDisplayedValues()[mNumberPickerDay.getValue()];
            mHour = mNumberPickerHour.getDisplayedValues()[mNumberPickerHour.getValue()];
            mMinute = mNumberPickerMinute.getDisplayedValues()[mNumberPickerMinute.getValue()];
            if (mCallback != null) {
                String year = null;
                String month = null;
                String day = null;
                String hour = null;
                String minute = null;
                if ((mType & TYPE_DATE) == TYPE_DATE) {
                    year = mShowYear ? mYear : null;
                    month = mShowMonth ? mMonth : null;
                    day = mShowDay ? mDay : null;
                }
                if ((mType & TYPE_TIME) == TYPE_TIME) {
                    hour = mShowHour ? mHour : null;
                    minute = mShowMinute ? mMinute : null;
                }
                mCallback.onDateChange(year, month, day, hour, minute);
            }
        }
    }


    @Override
    public void show() {
        super.show();
        setSelectedYear(mYear);
        setSelectedMonth(mMonth);
        setSelectedDay(mDay);
        setSelectedHour(mHour);
        setSelectedMinute(mMinute);
    }

    /**
     * 设置日期
     *
     * @param year  年 :
     * @param month 月 :
     * @param day   日
     */
    public void setDate(String year, String month, String day) {
        if (StringUtils.isNumber(year)) {
            this.mYear = TimeUtils.addZero(year);
        }
        if (StringUtils.isNumber(month)) {
            this.mMonth = TimeUtils.addZero(month);
        }
        if (StringUtils.isNumber(day)) {
            this.mDay = TimeUtils.addZero(day);
        }
    }

    /**
     * @param date
     * @param pattern yyyy-MM-dd
     */
    public void setDate(String date, String pattern) {
        if (!StringUtils.isNullOrEmpty(date)) {
            if (pattern == null) {
                pattern = PATTERN_DATE;
            }
            try {
                Date parse = TimeUtils.parse(date, pattern);
                Calendar c = Calendar.getInstance();
                c.setTime(parse);
                this.mYear = TimeUtils.addZero(c.get(Calendar.YEAR) + "");
                this.mMonth = TimeUtils.addZero((c.get(Calendar.MONTH) + 1) + "");
                this.mDay = TimeUtils.addZero(c.get(Calendar.DAY_OF_MONTH) + "");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 设置最大日期
     *
     * @param maxYear  最大年
     * @param maxMonth 最大月
     * @param maxDay   最大日
     */
    public void setMaxDate(String maxYear, String maxMonth, String maxDay) {
        this.mMaxYear = TimeUtils.addZero(maxYear);
        this.mMaxMonth = TimeUtils.addZero(maxMonth);
        this.mMaxDay = TimeUtils.addZero(maxDay);
    }

    /**
     * 设置最大日期
     *
     * @param date
     * @param pattern yyyy-MM-dd
     */
    public void setMaxDate(String date, String pattern) {
        if (!StringUtils.isNullOrEmpty(date)) {
            if (pattern == null) {
                pattern = PATTERN_DATE;
            }
            try {
                Date parse = TimeUtils.parse(date, pattern);
                Calendar c = Calendar.getInstance();
                c.setTime(parse);
                this.mMaxYear = TimeUtils.addZero(c.get(Calendar.YEAR) + "");
                this.mMaxMonth = TimeUtils.addZero((c.get(Calendar.MONTH) + 1) + "");
                this.mMaxDay = TimeUtils.addZero(c.get(Calendar.DAY_OF_MONTH) + "");
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            mMaxYear = null;
            mMaxMonth = null;
            mMaxDay = null;
        }
    }

    public void setMaxDate(Date date) {
        if (date != null) {
            Calendar c = Calendar.getInstance();
            c.setTime(date);
            this.mMaxYear = TimeUtils.addZero(c.get(Calendar.YEAR) + "");
            this.mMaxMonth = TimeUtils.addZero((c.get(Calendar.MONTH) + 1) + "");
            this.mMaxDay = TimeUtils.addZero(c.get(Calendar.DAY_OF_MONTH) + "");
        } else {
            mMaxYear = null;
            mMaxMonth = null;
            mMaxDay = null;
        }

    }

    /**
     * 设置时间
     *
     * @param hour   时
     * @param minute 分
     */
    public void setTime(String hour, String minute) {
        if (StringUtils.isNumber(hour)) {
            this.mHour = TimeUtils.addZero(hour);
        }
        if (StringUtils.isNumber(minute)) {
            this.mMinute = TimeUtils.addZero(minute);
        }
    }


    /**
     * 设置选择日期类型
     *
     * @param type {@link #TYPE_DATE#TYPE_TIME#TYPE_ALL}
     */
    public void setType(int type) {
        this.mType = type;
    }

    public int getType() {
        return mType;
    }

    public void showDay(boolean showDay) {
        this.mShowDay = showDay;
        if (mNumberPickerDay != null) {
            if (showDay) {
                mNumberPickerDay.setVisibility(View.VISIBLE);
                mDateTvDay.setVisibility(View.VISIBLE);
            } else {
                mNumberPickerDay.setVisibility(View.GONE);
                mDateTvDay.setVisibility(View.GONE);
            }
        }

    }

    public void showYear(boolean showYear) {
        this.mShowYear = showYear;
        if (mNumberPickerYear != null) {
            if (showYear) {
                mNumberPickerYear.setVisibility(View.VISIBLE);
                mDateTvYear.setVisibility(View.VISIBLE);
            } else {
                mNumberPickerYear.setVisibility(View.GONE);
                mDateTvYear.setVisibility(View.GONE);
            }
        }
    }

    public void showMonth(boolean showMonth) {
        this.mShowMonth = showMonth;
        if (mNumberPickerMonth != null) {
            if (showMonth) {
                mNumberPickerMonth.setVisibility(View.VISIBLE);
                mDateTvMonth.setVisibility(View.VISIBLE);
            } else {
                mNumberPickerMonth.setVisibility(View.GONE);
                mDateTvMonth.setVisibility(View.GONE);
            }
        }
    }

    public void showHour(boolean showHour) {
        this.mShowHour = showHour;
        if (mNumberPickerHour != null) {
            if (showHour) {
                mNumberPickerHour.setVisibility(View.VISIBLE);
                mDateTvHour.setVisibility(View.VISIBLE);
            } else {
                mNumberPickerHour.setVisibility(View.GONE);
                mDateTvHour.setVisibility(View.GONE);
            }
        }
    }

    public void showMinute(boolean showMinute) {
        this.mShowMinute = showMinute;
        if (mNumberPickerMinute != null) {
            if (showMinute) {
                mNumberPickerMinute.setVisibility(View.VISIBLE);
                mDateTvMinute.setVisibility(View.VISIBLE);
            } else {
                mNumberPickerMinute.setVisibility(View.GONE);
                mDateTvMinute.setVisibility(View.GONE);
            }
        }
    }


    public void setOrientation(int mOrientation) {
        this.mOrientation = mOrientation;
    }

    public void setCallback(Callback callback) {
        this.mCallback = callback;
    }


    public interface Callback {
        void onDateChange(String year, String month, String day, String hour, String minute);
    }
}
